package com.ai.agent.model;

import cn.hutool.core.util.StrUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 抽象基础代理类，用于管理代理状态和执行流程。
 * 提供状态转换、内存管理和基于步骤的执行循环的基础功能。
 * 子类必须实现step方法。
 */
@Data
@Slf4j
public abstract class BaseAgent {


    // 核心属性
    private String name;

    // 提示
    private String systemPrompt;
    private String nextStepPrompt;

    // 状态，默认为空闲
    private AgentState state = AgentState.IDLE;
    //执行控制
    private int maxSteps = 10;
    private int currentStep = 0;

    // LLM
    private ChatClient chatClient;

    // Memory 需要自主维护消息上下文
    private List<Message> messagesList = new ArrayList<>();

    /**
     * 运行代理 (流式输出）
     *
     * @param userPrompt 用户提示词
     * @return SseEmitter实例
     */
    public SseEmitter runStream(String userPrompt) {

        // 创建一个超时时间 的 SseEmitter 3分钟
        SseEmitter emitter = new SseEmitter(180000L);

        /**
         * CompletableFuture.runAsync() 实现非阻塞式异步执行，否则会长时间占用 Web 服务器线程池资源
         */
        CompletableFuture.runAsync(() -> {
            try {
                if (this.state != AgentState.IDLE) {
                    emitter.send("错误：无法从状态运行代理: " + this.state);
                    emitter.complete();
                    return ;
                }
                if (StrUtil.isBlank(userPrompt)) {
                    emitter.send("错误：不能使用空提示词运行代理");
                    emitter.complete();
                    return ;
                }

                //更改状态
                state = AgentState.RUNNING;
                // 记录消息上下文
                messagesList.add(new UserMessage(userPrompt));

                try {
                    for (int i = 0; i <= maxSteps && state != AgentState.FINISHED; i++) {
                        int stepNumber = i + 1;
                        currentStep = stepNumber;
                        log.info("Executing step " + stepNumber + "/" + maxSteps);

                        // 单步执行
                        String stepResult = step();
                        String result = "Step " + stepNumber + ":" + stepResult;

                        // 发送每一步的结果
                        emitter.send(result);

                    }
                    // 检查是否超出步骤限制
                    if (currentStep >= maxSteps) {
                        state = AgentState.FINISHED;
                        emitter.send("执行结束: 达到最大步骤 (" + maxSteps + ")");
                    }
                    emitter.complete();
                } catch (Exception e) {
                    state = AgentState.ERROR;
                    log.error("执行智能体失败", e);
                    try {
                        emitter.send("执行错误: " + e.getMessage());
                        emitter.complete();
                    }catch (Exception e1){
                        emitter.completeWithError(e1);
                    }
                } finally {
                    // 清理资源
                    this.cleanup();
                }
            } catch (IOException e) {
                emitter.completeWithError(e);
            }
        });

        emitter.onTimeout(()->{
            this.state = AgentState.ERROR;
            this.cleanup();
            log.warn("SSE connection timed out");
        });
        emitter.onCompletion(()->{
            if (state == AgentState.RUNNING) {
                this.state = AgentState.FINISHED;
            }
            this.cleanup();
            log.info("SSE connection completed");
        });

        return emitter;
    }

    /**
     * 执行单个步骤
     *
     * @return 步骤的执行结果
     */
    public abstract String step();
    /**
     * 清理资源
     */
    protected void cleanup() {}



}
